package com.isoft.airportsystem.controller.system;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.isoft.airportsystem.annotation.RequiresPermission;
import com.isoft.airportsystem.common.change.Result;
import com.isoft.airportsystem.entity.system.User;
import com.isoft.airportsystem.service.system.UserService;
import com.isoft.airportsystem.service.system.AuthService;
import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.http.HttpSession;

/**
 * 用户管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/system/user")
@CrossOrigin(origins = {"http://localhost:8080", "http://localhost:3000", "http://localhost:5173"}, allowCredentials = "true")
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    private static final Map<Long, Long> PASSWORD_RESET_TIMES = new HashMap<>();
    private static final long RESET_COOLDOWN = TimeUnit.MINUTES.toMillis(1);

    @Autowired
    private UserService userService;

    @Autowired
    private AuthService authService;

    /**
     * 分页查询用户列表
     */
    @RequiresPermission("system:user:list")
    @GetMapping("/list")
    public Result<Page<User>> list(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            User user) {
        Page<User> page = new Page<>(current, size);
        Page<User> result = userService.selectUserPage(page, user);
        return Result.success(result);
    }

    /**
     * 获取所有用户列表（用于下拉选择）
     */
    @GetMapping("/all")
    public Result<List<User>> getAllUsers(HttpSession session) {
        if (session.getAttribute("userId") == null) {
            return Result.fail("未登录或会话失效");
        }
        List<User> users = userService.selectAllUsers();
        return Result.success(users);
    }

    /**
     * 根据ID查询用户
     */
    @RequiresPermission("system:user:query")
    @GetMapping("/{userId}")
    public Result<User> getById(@PathVariable Long userId) {
        User user = userService.selectUserById(userId);
        return Result.success(user);
    }

    /**
     * 新增用户
     */
    @RequiresPermission("system:user:add")
    @PostMapping
    public Result<?> add(@RequestBody User user, @RequestParam(required = false) Long[] roleIds) {
        // 加密密码
        if (user.getPassword() != null) {
            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }

        boolean result = userService.insertUser(user, roleIds);
        return result ? Result.success("新增成功") : Result.fail("新增失败");
    }

    /**
     * 修改用户
     */
    @RequiresPermission("system:user:edit")
    @PutMapping
    public Result<?> update(@RequestBody com.isoft.airportsystem.dto.UserUpdateDTO dto) {
        com.isoft.airportsystem.entity.system.User user = dto.getUser();
        java.util.List<Long> roleIds = dto.getRoleIds();
        // 如果密码不为空，则加密密码
        if (user.getPassword() != null && !user.getPassword().trim().isEmpty()) {
            user.setPassword(org.springframework.util.DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }
        boolean result = userService.updateUser(user, roleIds == null ? null : roleIds.toArray(new Long[0]));
        return result ? Result.success("修改成功") : Result.fail("修改失败");
    }

    /**
     * 删除用户
     */
    @RequiresPermission("system:user:remove")
    @DeleteMapping("/{userId}")
    public Result<?> delete(@PathVariable Long userId) {
        boolean result = userService.deleteUserById(userId);
        return result ? Result.success("删除成功") : Result.fail("删除失败");
    }

    /**
     * 批量删除用户
     */
    @RequiresPermission("system:user:remove")
    @DeleteMapping("/batch/{userIds}")
    public Result<?> batchDelete(@PathVariable Long[] userIds) {
        boolean result = userService.deleteUserByIds(userIds);
        return result ? Result.success("批量删除成功") : Result.fail("批量删除失败");
    }

    /**
     * 重置用户密码
     */
    @RequiresPermission("system:user:resetPwd")
    @PutMapping("/{userId}/reset-password")
    public Result<?> resetPassword(@PathVariable Long userId, @RequestParam String password) {
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        boolean result = userService.resetPassword(userId, encryptedPassword);
        return result ? Result.success("密码重置成功") : Result.fail("密码重置失败");
    }

    /**
     * 修改用户状态
     */
    @RequiresPermission("system:user:edit")
    @PutMapping("/{userId}/status")
    public Result<?> updateStatus(@PathVariable Long userId, @RequestParam Integer status) {
        boolean result = userService.updateUserStatus(userId, status);
        return result ? Result.success("状态修改成功") : Result.fail("状态修改失败");
    }

    /**
     * 查询用户角色ID列表
     */
    @RequiresPermission("system:user:query")
    @GetMapping("/{userId}/roles")
    public Result<List<Long>> getUserRoles(@PathVariable Long userId) {
        List<Long> roleIds = userService.selectRoleIdsByUserId(userId);
        return Result.success(roleIds);
    }

    /**
     * 查询用户权限列表
     */
    @RequiresPermission("system:user:query")
    @GetMapping("/{userId}/permissions")
    public Result<List<String>> getUserPermissions(@PathVariable Long userId) {
        List<String> permissions = userService.selectPermissionsByUserId(userId);
        return Result.success(permissions);
    }

    /**
     * 更新个人资料
     */
    @PutMapping("/profile")
    public Map<String, Object> updateProfile(@RequestBody User user, HttpSession session) {
        // 参数验证
        if (user.getUserId() == null) {
            return errorResponse(400, "用户ID不能为空");
        }
        // 校验只能改自己
        Long loginUserId = (Long) session.getAttribute("userId");
        if (loginUserId == null || !user.getUserId().equals(loginUserId)) {
            return errorResponse(403, "无权修改他人信息");
        }
        // 只允许更新特定字段：真实姓名、手机号、邮箱、备注
        User updateUser = new User();
        updateUser.setUserId(user.getUserId());
        updateUser.setRealName(user.getRealName());
        updateUser.setPhone(user.getPhone());
        updateUser.setEmail(user.getEmail());
        updateUser.setRemark(user.getRemark());
        updateUser.setUpdateTime(LocalDateTime.now());

        boolean result = userService.updateUserSelective(updateUser);

        logger.info("更新个人资料: ID={}, 结果={}", user.getUserId(), result ? "成功" : "失败");

        return response(result, "个人资料更新成功", "个人资料更新失败");
    }

    /**
     * 修改密码
     */
    @PutMapping("/password")
    public Map<String, Object> changePassword(@RequestBody Map<String, String> request) {
        Long userId = Long.valueOf(request.get("userId"));
        String oldPassword = request.get("oldPassword");
        String newPassword = request.get("newPassword");

        // 参数验证
        if (userId == null || StringUtils.isBlank(oldPassword) || StringUtils.isBlank(newPassword)) {
            return errorResponse(400, "参数不完整");
        }

        // 验证旧密码
        User user = userService.selectUserById(userId);
        if (user == null) {
            return errorResponse(404, "用户不存在");
        }

        String encryptedOldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        if (!encryptedOldPassword.equals(user.getPassword())) {
            return errorResponse(400, "当前密码错误");
        }

        // 验证新密码强度
        if (!authService.checkPasswordStrength(newPassword)) {
            return errorResponse(400, "新密码必须包含大小写字母、数字和特殊字符，长度至少8位");
        }

        // 更新密码
        String encryptedNewPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        User updateUser = new User();
        updateUser.setUserId(userId);
        updateUser.setPassword(encryptedNewPassword);
        updateUser.setUpdateTime(LocalDateTime.now());

        boolean result = userService.updateUserSelective(updateUser);

        logger.info("修改密码: ID={}, 结果={}", userId, result ? "成功" : "失败");

        return response(result, "密码修改成功", "密码修改失败");
    }

    /**
     * 初始化测试数据
     */
    @PostMapping("/initTestData")
    public Map<String, Object> initTestData() {
        try {
            // 检查是否已有用户数据
            Page<User> page = new Page<>(1, 1);
            Page<User> userPage = userService.selectUserPage(page, null);

            if (userPage.getTotal() == 0) {
                // 创建测试用户
                User testUser = new User();
                testUser.setUsername("admin");
                testUser.setPassword(DigestUtils.md5DigestAsHex("Admin123!".getBytes()));
                testUser.setRealName("系统管理员");
                testUser.setPhone("13800138000");
                testUser.setEmail("admin@example.com");
                testUser.setStatus(1);
                testUser.setDelFlag(0);

                boolean result = userService.insertUser(testUser, null);
                if (result) {
                    logger.info("测试用户数据初始化成功");
                    return response(true, "测试数据初始化成功", "测试数据初始化失败");
                } else {
                    return response(false, "测试数据初始化成功", "测试数据初始化失败");
                }
            } else {
                return response(true, "数据库中已有用户数据", "数据库中已有用户数据");
            }
        } catch (Exception e) {
            logger.error("初始化测试数据失败", e);
            return errorResponse(500, "初始化测试数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户信息（所有有 self-info:view 权限的用户可访问）
     */
    @RequiresPermission("self-info:view")
    @GetMapping("/current")
    public Result<User> getCurrentUser(HttpSession session) {
        Long loginUserId = (Long) session.getAttribute("userId");
        if (loginUserId == null) {
            return Result.fail("未登录或会话失效");
        }
        User user = userService.selectUserById(loginUserId);
        if (user == null) {
            return Result.fail("用户不存在");
        }
        return Result.success(user);
    }

    private Map<String, Object> response(boolean success, String successMsg, String errorMsg) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", success ? 200 : 500);
        map.put("msg", success ? successMsg : errorMsg);
        return map;
    }

    private Map<String, Object> errorResponse(int code, String message) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("msg", message);
        return map;
    }
}